package org.springblade.modules.admin.task.feishu;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.enums.FeiShuDocumentEnum;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.feishu.FeiShuBatchDTO;
import org.springblade.modules.admin.dto.feishu.FeiShuFieldsDTO;
import org.springblade.modules.admin.enums.ComplianceStatusEnum;
import org.springblade.modules.admin.enums.ContractStatusEnum;
import org.springblade.modules.admin.enums.ElevatorMaintainStatusEnums;
import org.springblade.modules.admin.service.IMaintainPlanConfigService;
import org.springblade.modules.admin.service.feishu.IFeiShuDocumentService;
import org.springblade.modules.admin.vo.MaintainPlanConfigVO;
import org.springblade.modules.admin.vo.feishu.LarkMaintainPlanConfigVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 凤仪的飞书保养业务风险管理数据表，仅银河租户
 * @author: Sharry
 * @createTime: 2024-05-14 14:40
 * @version: Version-1.0
 */
@Component
@Slf4j
public class LarkElevatorMaintenanceRiskDataJob {

	@Autowired
	private IFeiShuDocumentService feiShuDocumentService;

	@Autowired
	private IMaintainPlanConfigService maintainPlanConfigService;

	/**
	 * 凤仪的飞书保养业务风险管理数据表_副本_定时任务，用于监测
	 * key：电梯唯一识别码
	 * 执行时间：
	 *   - 早：8:00am
	 *   - 中：12：00am
	 *   - 下午：16：00pm
	 *   每天共3次，cron 表达式： 0 0 8,12,16 * * ?
	 */
	@XxlJob("galaxyElevatorMaintenanceRiskDataJobCopy")
	public void galaxyElevatorMaintenanceRiskDataJobCopy(){
		XxlJobHelper.handleSuccess("定时任务更新凤仪的飞书保养业务风险管理数据表-[执行]开始");
		try{
			// 1. 数据准备：appToken、tableId、要更新的梯无忧列表、当前飞书多维表格的列表
			String appToken = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_RISK_DATA_COPY.getAppToken();
			String tableId = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_RISK_DATA_COPY.getTableId();
			feiShuDocumentService.commandDistinctByKeyAndUpdateTime(appToken, tableId,"电梯快速识别码","最后更新时间");
			List<LarkMaintainPlanConfigVO> maintainPlanConfigVOList = maintainPlanConfigService.getLarkMaintainPlanConfigVOList();
			// 2. 数据处理、数据update
			// 2.1 复用分页逻辑处理在保信息
			List<Integer> maintainStatusList = Arrays.asList(
				ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId(),
				ElevatorMaintainStatusEnums.CONTRACT_OUT_TIME.getId(),
				ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId(),
				ElevatorMaintainStatusEnums.OUT_TIME_END.getId(),
				ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId(),
				ElevatorMaintainStatusEnums.DIS_ENABLE.getId()
			);
			for (LarkMaintainPlanConfigVO planConfig : maintainPlanConfigVOList) {
				if (maintainStatusList.contains(planConfig.getMaintainStatus())) {
					Integer useType = planConfig.getUseType();
					if (!Func.equalsSafe(useType, 0)) {
						continue;
					}
					int overdueCompare= DateUtil.compare(DateUtil.date(), planConfig.getOverdueDate(), "yyyy-MM-dd");
					// 合规状态描述
					if (overdueCompare < 0) {
						planConfig.setComplianceStatus(ComplianceStatusEnum.NORMAL.getId());
						planConfig.setComplianceStatusDesc("正常");
					} else if (overdueCompare == 0) {
						planConfig.setComplianceStatus(ComplianceStatusEnum.VIOLATING.getId());
						planConfig.setComplianceStatusDesc("明天即将违规");
					} else {
						planConfig.setComplianceStatus(ComplianceStatusEnum.VIOLATED.getId());
						planConfig.setComplianceStatusDesc("已违规");
						// 比较今天和计划的天数差
						if(!Func.isNull(planConfig.getOverdueDate())){
							long overdueDays = DateUtil.between(DateUtil.date(), planConfig.getOverdueDate(), DateUnit.DAY);
							planConfig.setOverdueDays((int)overdueDays);
						}

					}
				}
				if (planConfig.getNextPlanDate() != null) {
					int riskCompare= DateUtil.compare(planConfig.getNextPlanDate(), planConfig.getOverdueDate(), "yyyy-MM-dd");
					if (riskCompare <= 0) {
						planConfig.setIsOverdueRisk(false);
					} else {
						planConfig.setIsOverdueRisk(true);
					}
				}
			}
			// 2.2 数据封装,封装时做处理
			FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
			List<FeiShuFieldsDTO> records = new ArrayList<>();
			for (LarkMaintainPlanConfigVO larkMaintainPlanConfigVO : maintainPlanConfigVOList) {
				FeiShuFieldsDTO element = new FeiShuFieldsDTO();
				Map<String, Object> elementMap = new HashMap<>(30);
				elementMap.put("电梯快速识别码", larkMaintainPlanConfigVO.getElevatorNum());
				elementMap.put("省", larkMaintainPlanConfigVO.getProvinceName());
				elementMap.put("市", larkMaintainPlanConfigVO.getCityName());
				elementMap.put("区", larkMaintainPlanConfigVO.getAdName());
				Date overdueDate = larkMaintainPlanConfigVO.getOverdueDate();
				Long overdueDateTime = null;
				if(!Func.isNull(overdueDate)){
					overdueDateTime = overdueDate.getTime();
				}
				elementMap.put("电梯_当前逾期临界日期",overdueDateTime);
				elementMap.put("项目名称",larkMaintainPlanConfigVO.getBuildingName());
				elementMap.put("楼栋号",larkMaintainPlanConfigVO.getElevatorAddress());
				elementMap.put("项目地址",larkMaintainPlanConfigVO.getAddress());
				elementMap.put("梯型式",larkMaintainPlanConfigVO.getModeName());
				String fromTypeName = null;
				Integer fromType = larkMaintainPlanConfigVO.getFromType();
				if(!Func.isNull(fromType)){
					fromTypeName = new Integer(1).equals(fromType) ? "外包"
						: new Integer(2).equals(fromType) ? "非外包" : "无状态默认值";
				}
				elementMap.put("外包情况",fromTypeName);
				String useTypeName = null;
				Integer useType = larkMaintainPlanConfigVO.getUseType();
				if(!Func.isNull(useType)){
					useTypeName = new Integer(0).equals(useType) ? "年审" : "非年审";
				}
				elementMap.put("年审类型",useTypeName);
                elementMap.put("电梯所属维保组",
					Func.isNull(larkMaintainPlanConfigVO.getDeptName()) ? "无"
						: larkMaintainPlanConfigVO.getDeptName());
				String maintainStatusName = ElevatorMaintainStatusEnums.getName(larkMaintainPlanConfigVO.getMaintainStatus());
				elementMap.put("保养状态",maintainStatusName);
                elementMap.put("电梯状态",new Integer(1).equals(larkMaintainPlanConfigVO.getIsStop()) ? "正常运行" : "停梯");
				elementMap.put("年审梯保养合规状态",larkMaintainPlanConfigVO.getComplianceStatusDesc());
				if(!Func.isNull(larkMaintainPlanConfigVO.getOverdueDays())){
					elementMap.put("违规天数", larkMaintainPlanConfigVO.getOverdueDays());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getPreviousPlanDate())){
					elementMap.put("上次维保签字日期",larkMaintainPlanConfigVO.getPreviousPlanDate().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getNextPlanDate())){
					elementMap.put("下次保养计划日期",larkMaintainPlanConfigVO.getNextPlanDate().getTime());
				}else{
					elementMap.put("下次保养计划日期",null);
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getIsOverdueRisk())){
					elementMap.put("下次保养计划排期是否存在逾期风险",
					larkMaintainPlanConfigVO.getIsOverdueRisk() ? "是" : "否");
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getOtherOverdue())){
					elementMap.put("其他剩余计划是否存在逾期风险",
						new Integer(1).equals(larkMaintainPlanConfigVO.getOtherOverdue()) ? "是" : "否"
					);
				}
				// 凤仪的表格这个字段设计成如此，我也没办法，做多用List转Array但时间紧急先跑通再说
				String[] isPlans = new String[1];
				String isPlanDesc = new Integer(1).equals(larkMaintainPlanConfigVO.getIsPlan()) ? "有" : "无";
				isPlans[0] = isPlanDesc;
				elementMap.put("有无未来保养排期计划", isPlans);
				if(!Func.isNull(larkMaintainPlanConfigVO.getNextUserNames())){
					elementMap.put("下次保养计划执行人", larkMaintainPlanConfigVO.getNextUserNames().split(","));
				}
				elementMap.put("保养计划", larkMaintainPlanConfigVO.getTemplatePlanName());
				if(!Func.isNull(larkMaintainPlanConfigVO.getFirstTime())) {
					elementMap.put("首次保养日期", larkMaintainPlanConfigVO.getFirstTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getStartTime())) {
					elementMap.put("保养排期开始日期", larkMaintainPlanConfigVO.getStartTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getEndTime())){
					elementMap.put("保养排期结束日期",larkMaintainPlanConfigVO.getEndTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getUpdateTime())){
					elementMap.put("最后更新时间",larkMaintainPlanConfigVO.getUpdateTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getBuildingId())){
					elementMap.put("项目ID",String.valueOf(larkMaintainPlanConfigVO.getBuildingId()));
				}
				// 2024-08-29 新增
				elementMap.put("梯无忧_当前执行合同编号",larkMaintainPlanConfigVO.getContractNo());
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractBeginTime())){
					elementMap.put("梯无忧_合同服务时间(开始)",larkMaintainPlanConfigVO.getContractBeginTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractEndTime())) {
					elementMap.put("梯无忧_合同服务时间(结束)", larkMaintainPlanConfigVO.getContractEndTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractStatus())){
					Integer contractStatus = larkMaintainPlanConfigVO.getContractStatus();
					String name = ContractStatusEnum.getName(contractStatus);
					elementMap.put("梯无忧_当前执行合同管理状态",name);
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractId())) {
					String link1 = "https://admin.sida-tech.com/#/contractManage/seeContract?id=";
					Map<String, String> linkMap = new HashMap<>(2);
					linkMap.put("link", link1 + larkMaintainPlanConfigVO.getContractId());
					linkMap.put("text", "梯无忧_合同详情页链接");
					elementMap.put("梯无忧_合同详情页链接", linkMap);
				}
				elementMap.put("是否存在下一份合同",larkMaintainPlanConfigVO.getNextContractStatus());
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractSignSource())) {
					elementMap.put("合同签约来源", larkMaintainPlanConfigVO.getContractSignSource());
				}

				element.setFields(elementMap);
				records.add(element);
			}
			// 2.3 根据电梯识别码批量：更新、新增、删除飞书多维表格数据
			batchDTO.setRecords(records);
			String finalResult = feiShuDocumentService.commandCompareUpdateBatch(appToken, tableId, batchDTO, "电梯快速识别码");
			// 3. 发送飞书消息卡片到应用所在群聊
			List<JSONObject> targetGroupObjects = feiShuDocumentService.commandQueryGroupsBatch();
			List<String> chatIds = new ArrayList<>();
			targetGroupObjects.forEach(t -> chatIds.add(t.getString("chat_id")));
			// 发送消息
			chatIds.forEach(c -> {
				// 组装数据
				JSONObject bodyJson = new JSONObject();
				bodyJson.put("receive_id", c);
				bodyJson.put("msg_type", "text");
				HashMap<String, String> contentMap = new HashMap<>(2);
				String message = "定时器或表格按钮触发更新"+FeiShuDocumentEnum.getDescription(appToken,tableId)+"结果：" + finalResult;
				contentMap.put("text", message);
				// 将 contentMap 转换成 JSON 格式
				bodyJson.put("content", JSON.toJSONString(contentMap));
				feiShuDocumentService.commandSendGroupMessage(bodyJson.toJSONString());
			});
			XxlJobHelper.handleSuccess("定时任务更新凤仪的飞书保养业务风险管理数据表-[执行]成功");
		}catch (Exception e){
			XxlJobHelper.handleSuccess("定时任务更新凤仪的飞书保养业务风险管理数据表-[执行]失败"+e);
		}
	}

	/**
	 * 凤仪的飞书保养业务风险管理数据表_正本_定时任务，正式环境执行
	 * 执行时间：
	 *   - 早：8:00am
	 *   - 中：12：00am
	 *   - 下午：16：00pm
	 *   每天共3次，cron 表达式： 0 0 8,12,16 * * ?
	 */
	@XxlJob("galaxyElevatorMaintenanceRiskDataJob")
	public void galaxyElevatorMaintenanceRiskDataJob(){
		XxlJobHelper.handleSuccess("定时任务更新凤仪的飞书保养业务风险管理数据表-[执行]开始");
		try{
			// 1. 数据准备：appToken、tableId、要更新的梯无忧列表、当前飞书多维表格的列表
			String appToken = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_RISK_DATA.getAppToken();
			String tableId = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_RISK_DATA.getTableId();
			feiShuDocumentService.commandDistinctByKeyAndUpdateTime(appToken, tableId,"电梯快速识别码","最后更新时间");
			List<LarkMaintainPlanConfigVO> maintainPlanConfigVOList = maintainPlanConfigService.getLarkMaintainPlanConfigVOList();
			// 2. 数据处理、数据update
			// 2.1 复用分页逻辑处理在保信息
			List<Integer> maintainStatusList = Arrays.asList(
				ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId(),
				ElevatorMaintainStatusEnums.CONTRACT_OUT_TIME.getId(),
				ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId(),
				ElevatorMaintainStatusEnums.OUT_TIME_END.getId(),
				ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId(),
				ElevatorMaintainStatusEnums.DIS_ENABLE.getId()
			);
			for (LarkMaintainPlanConfigVO planConfig : maintainPlanConfigVOList) {
				if (maintainStatusList.contains(planConfig.getMaintainStatus())) {
					Integer useType = planConfig.getUseType();
					if (!Func.equalsSafe(useType, 0)) {
						continue;
					}
					int overdueCompare= DateUtil.compare(DateUtil.date(), planConfig.getOverdueDate(), "yyyy-MM-dd");
					// 合规状态描述
					if (overdueCompare < 0) {
						planConfig.setComplianceStatus(ComplianceStatusEnum.NORMAL.getId());
						planConfig.setComplianceStatusDesc("正常");
					} else if (overdueCompare == 0) {
						planConfig.setComplianceStatus(ComplianceStatusEnum.VIOLATING.getId());
						planConfig.setComplianceStatusDesc("明天即将违规");
					} else {
						planConfig.setComplianceStatus(ComplianceStatusEnum.VIOLATED.getId());
						planConfig.setComplianceStatusDesc("已违规");
						// 比较今天和计划的天数差
						if(!Func.isNull(planConfig.getOverdueDate())){
							long overdueDays = DateUtil.between(DateUtil.date(), planConfig.getOverdueDate(), DateUnit.DAY);
							planConfig.setOverdueDays((int)overdueDays);
						}

					}
				}
				if (planConfig.getNextPlanDate() != null) {
					int riskCompare= DateUtil.compare(planConfig.getNextPlanDate(), planConfig.getOverdueDate(), "yyyy-MM-dd");
					if (riskCompare <= 0) {
						planConfig.setIsOverdueRisk(false);
					} else {
						planConfig.setIsOverdueRisk(true);
					}
				}
			}
			// 2.2 数据封装,封装时做处理
			FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
			List<FeiShuFieldsDTO> records = new ArrayList<>();
			for (LarkMaintainPlanConfigVO larkMaintainPlanConfigVO : maintainPlanConfigVOList) {
				FeiShuFieldsDTO element = new FeiShuFieldsDTO();
				Map<String, Object> elementMap = new HashMap<>(30);
				elementMap.put("电梯快速识别码", larkMaintainPlanConfigVO.getElevatorNum());
				elementMap.put("省", larkMaintainPlanConfigVO.getProvinceName());
				elementMap.put("市", larkMaintainPlanConfigVO.getCityName());
				elementMap.put("区", larkMaintainPlanConfigVO.getAdName());
				Date overdueDate = larkMaintainPlanConfigVO.getOverdueDate();
				Long overdueDateTime = null;
				if(!Func.isNull(overdueDate)){
					overdueDateTime = overdueDate.getTime();
				}
				elementMap.put("电梯_当前逾期临界日期",overdueDateTime);
				elementMap.put("项目名称",larkMaintainPlanConfigVO.getBuildingName());
				elementMap.put("楼栋号",larkMaintainPlanConfigVO.getElevatorAddress());
				elementMap.put("项目地址",larkMaintainPlanConfigVO.getAddress());
				elementMap.put("梯型式",larkMaintainPlanConfigVO.getModeName());
				String fromTypeName = null;
				Integer fromType = larkMaintainPlanConfigVO.getFromType();
				if(!Func.isNull(fromType)){
					fromTypeName = new Integer(1).equals(fromType) ? "外包"
						: new Integer(2).equals(fromType) ? "非外包" : "无状态默认值";
				}
				elementMap.put("外包情况",fromTypeName);
				String useTypeName = null;
				Integer useType = larkMaintainPlanConfigVO.getUseType();
				if(!Func.isNull(useType)){
					useTypeName = new Integer(0).equals(useType) ? "年审" : "非年审";
				}
				elementMap.put("年审类型",useTypeName);
				elementMap.put("电梯所属维保组",
					Func.isNull(larkMaintainPlanConfigVO.getDeptName()) ? "无"
						: larkMaintainPlanConfigVO.getDeptName());
				String maintainStatusName = ElevatorMaintainStatusEnums.getName(larkMaintainPlanConfigVO.getMaintainStatus());
				elementMap.put("保养状态",maintainStatusName);
				elementMap.put("电梯状态",new Integer(1).equals(larkMaintainPlanConfigVO.getIsStop()) ? "正常运行" : "停梯");
				elementMap.put("年审梯保养合规状态",larkMaintainPlanConfigVO.getComplianceStatusDesc());
				if(!Func.isNull(larkMaintainPlanConfigVO.getOverdueDays())){
					elementMap.put("违规天数", larkMaintainPlanConfigVO.getOverdueDays());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getPreviousPlanDate())){
					elementMap.put("上次维保签字日期",larkMaintainPlanConfigVO.getPreviousPlanDate().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getNextPlanDate())){
					elementMap.put("下次保养计划日期",larkMaintainPlanConfigVO.getNextPlanDate().getTime());
				}else{
					elementMap.put("下次保养计划日期",null);
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getIsOverdueRisk())){
					elementMap.put("下次保养计划排期是否存在逾期风险",
						larkMaintainPlanConfigVO.getIsOverdueRisk() ? "是" : "否");
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getOtherOverdue())){
					elementMap.put("其他剩余计划是否存在逾期风险",
						new Integer(1).equals(larkMaintainPlanConfigVO.getOtherOverdue()) ? "是" : "否"
					);
				}
				// 凤仪的表格这个字段设计成如此，我也没办法，做多用List转Array但时间紧急先跑通再说
				String[] isPlans = new String[1];
				String isPlanDesc = new Integer(1).equals(larkMaintainPlanConfigVO.getIsPlan()) ? "有" : "无";
				isPlans[0] = isPlanDesc;
				elementMap.put("有无未来保养排期计划", isPlans);
				if(!Func.isNull(larkMaintainPlanConfigVO.getNextUserNames())){
					elementMap.put("下次保养计划执行人", larkMaintainPlanConfigVO.getNextUserNames().split(","));
				}
				elementMap.put("保养计划", larkMaintainPlanConfigVO.getTemplatePlanName());
				if(!Func.isNull(larkMaintainPlanConfigVO.getFirstTime())) {
					elementMap.put("首次保养日期", larkMaintainPlanConfigVO.getFirstTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getStartTime())) {
					elementMap.put("保养排期开始日期", larkMaintainPlanConfigVO.getStartTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getEndTime())){
					elementMap.put("保养排期结束日期",larkMaintainPlanConfigVO.getEndTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getUpdateTime())){
					elementMap.put("最后更新时间",larkMaintainPlanConfigVO.getUpdateTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getBuildingId())){
					elementMap.put("项目ID",String.valueOf(larkMaintainPlanConfigVO.getBuildingId()));
				}
				// 2024-08-29 新增
				elementMap.put("梯无忧_当前执行合同编号",larkMaintainPlanConfigVO.getContractNo());
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractBeginTime())){
					elementMap.put("梯无忧_合同服务时间(开始)",larkMaintainPlanConfigVO.getContractBeginTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractEndTime())) {
					elementMap.put("梯无忧_合同服务时间(结束)", larkMaintainPlanConfigVO.getContractEndTime().getTime());
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractStatus())){
					Integer contractStatus = larkMaintainPlanConfigVO.getContractStatus();
					String name = ContractStatusEnum.getName(contractStatus);
					elementMap.put("梯无忧_当前执行合同管理状态",name);
				}
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractId())) {
					String link1 = "https://admin.sida-tech.com/#/contractManage/seeContract?id=";
					Map<String, String> linkMap = new HashMap<>(2);
					linkMap.put("link", link1 + larkMaintainPlanConfigVO.getContractId());
					linkMap.put("text", "梯无忧_合同详情页链接");
					elementMap.put("梯无忧_合同详情页链接", linkMap);
				}
				elementMap.put("是否存在下一份合同",larkMaintainPlanConfigVO.getNextContractStatus());
				if(!Func.isNull(larkMaintainPlanConfigVO.getContractSignSource())) {
					elementMap.put("合同签约来源", larkMaintainPlanConfigVO.getContractSignSource());
				}
				element.setFields(elementMap);
				records.add(element);
			}
			// 2.3 根据电梯识别码批量：更新、新增、删除飞书多维表格数据
			batchDTO.setRecords(records);
			String finalResult = feiShuDocumentService.commandCompareUpdateBatch(appToken, tableId, batchDTO, "电梯快速识别码");
			// 3. 发送飞书消息卡片到应用所在群聊
			List<JSONObject> targetGroupObjects = feiShuDocumentService.commandQueryGroupsBatch();
			List<String> chatIds = new ArrayList<>();
			targetGroupObjects.forEach(t -> chatIds.add(t.getString("chat_id")));
			// 发送消息
			chatIds.forEach(c -> {
				// 组装数据
				JSONObject bodyJson = new JSONObject();
				bodyJson.put("receive_id", c);
				bodyJson.put("msg_type", "text");
				HashMap<String, String> contentMap = new HashMap<>(2);
				String message = "定时器或表格按钮触发更新"+FeiShuDocumentEnum.getDescription(appToken,tableId)+"结果：" + finalResult;
				contentMap.put("text", message);
				// 将 contentMap 转换成 JSON 格式
				bodyJson.put("content", JSON.toJSONString(contentMap));
				feiShuDocumentService.commandSendGroupMessage(bodyJson.toJSONString());
			});
			XxlJobHelper.handleSuccess("定时任务更新凤仪的飞书保养业务风险管理数据表-[执行]成功");
		}catch (Exception e){
			XxlJobHelper.handleSuccess("定时任务更新银河租户电梯识别码信息-[执行]失败"+e);
		}
	}

	/**
	 * 异步执行方法
	 */
	@Async
	public void galaxyElevatorMaintenanceRiskDataCopyAsync() {
		// 1. 数据准备：appToken、tableId、要更新的梯无忧列表、当前飞书多维表格的列表
		String appToken = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_RISK_DATA_COPY.getAppToken();
		String tableId = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_RISK_DATA_COPY.getTableId();
		feiShuDocumentService.commandDistinctByKeyAndUpdateTime(appToken, tableId,"电梯快速识别码","最后更新时间");
		List<LarkMaintainPlanConfigVO> maintainPlanConfigVOList = maintainPlanConfigService.getLarkMaintainPlanConfigVOList();
		// 2. 数据处理、数据update
		// 2.1 复用分页逻辑处理在保信息
		List<Integer> maintainStatusList = Arrays.asList(
			ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId(),
			ElevatorMaintainStatusEnums.CONTRACT_OUT_TIME.getId(),
			ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId(),
			ElevatorMaintainStatusEnums.OUT_TIME_END.getId(),
			ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId(),
			ElevatorMaintainStatusEnums.DIS_ENABLE.getId()
		);
		for (LarkMaintainPlanConfigVO planConfig : maintainPlanConfigVOList) {
			if (maintainStatusList.contains(planConfig.getMaintainStatus())) {
				Integer useType = planConfig.getUseType();
				if (!Func.equalsSafe(useType, 0)) {
					continue;
				}
				int overdueCompare= DateUtil.compare(DateUtil.date(), planConfig.getOverdueDate(), "yyyy-MM-dd");
				// 合规状态描述
				if (overdueCompare < 0) {
					planConfig.setComplianceStatus(ComplianceStatusEnum.NORMAL.getId());
					planConfig.setComplianceStatusDesc("正常");
				} else if (overdueCompare == 0) {
					planConfig.setComplianceStatus(ComplianceStatusEnum.VIOLATING.getId());
					planConfig.setComplianceStatusDesc("明天即将违规");
				} else {
					planConfig.setComplianceStatus(ComplianceStatusEnum.VIOLATED.getId());
					planConfig.setComplianceStatusDesc("已违规");
					// 比较今天和计划的天数差
					if(!Func.isNull(planConfig.getOverdueDate())){
						long overdueDays = DateUtil.between(DateUtil.date(), planConfig.getOverdueDate(), DateUnit.DAY);
						planConfig.setOverdueDays((int)overdueDays);
					}

				}
			}
			if (planConfig.getNextPlanDate() != null) {
				int riskCompare= DateUtil.compare(planConfig.getNextPlanDate(), planConfig.getOverdueDate(), "yyyy-MM-dd");
				if (riskCompare <= 0) {
					planConfig.setIsOverdueRisk(false);
				} else {
					planConfig.setIsOverdueRisk(true);
				}
			}
		}
		// 2.2 数据封装,封装时做处理
		FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
		List<FeiShuFieldsDTO> records = new ArrayList<>();
		for (LarkMaintainPlanConfigVO larkMaintainPlanConfigVO : maintainPlanConfigVOList) {
			FeiShuFieldsDTO element = new FeiShuFieldsDTO();
			Map<String, Object> elementMap = new HashMap<>(30);
			elementMap.put("电梯快速识别码", larkMaintainPlanConfigVO.getElevatorNum());
			elementMap.put("省", larkMaintainPlanConfigVO.getProvinceName());
			elementMap.put("市", larkMaintainPlanConfigVO.getCityName());
			elementMap.put("区", larkMaintainPlanConfigVO.getAdName());
			Date overdueDate = larkMaintainPlanConfigVO.getOverdueDate();
			Long overdueDateTime = null;
			if(!Func.isNull(overdueDate)){
				overdueDateTime = overdueDate.getTime();
			}
			elementMap.put("电梯_当前逾期临界日期",overdueDateTime);
			elementMap.put("项目名称",larkMaintainPlanConfigVO.getBuildingName());
			elementMap.put("楼栋号",larkMaintainPlanConfigVO.getElevatorAddress());
			elementMap.put("项目地址",larkMaintainPlanConfigVO.getAddress());
			elementMap.put("梯型式",larkMaintainPlanConfigVO.getModeName());
			String fromTypeName = null;
			Integer fromType = larkMaintainPlanConfigVO.getFromType();
			if(!Func.isNull(fromType)){
				fromTypeName = new Integer(1).equals(fromType) ? "外包"
					: new Integer(2).equals(fromType) ? "非外包" : "无状态默认值";
			}
			elementMap.put("外包情况",fromTypeName);
			String useTypeName = null;
			Integer useType = larkMaintainPlanConfigVO.getUseType();
			if(!Func.isNull(useType)){
				useTypeName = new Integer(0).equals(useType) ? "年审" : "非年审";
			}
			elementMap.put("年审类型",useTypeName);
			elementMap.put("电梯所属维保组",
				Func.isNull(larkMaintainPlanConfigVO.getDeptName()) ? "无"
					: larkMaintainPlanConfigVO.getDeptName());
			String maintainStatusName = ElevatorMaintainStatusEnums.getName(larkMaintainPlanConfigVO.getMaintainStatus());
			elementMap.put("保养状态",maintainStatusName);
			elementMap.put("电梯状态",new Integer(1).equals(larkMaintainPlanConfigVO.getIsStop()) ? "正常运行" : "停梯");
			elementMap.put("年审梯保养合规状态",larkMaintainPlanConfigVO.getComplianceStatusDesc());
			if(!Func.isNull(larkMaintainPlanConfigVO.getOverdueDays())){
				elementMap.put("违规天数", larkMaintainPlanConfigVO.getOverdueDays());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getPreviousPlanDate())){
				elementMap.put("上次维保签字日期",larkMaintainPlanConfigVO.getPreviousPlanDate().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getNextPlanDate())){
				elementMap.put("下次保养计划日期",larkMaintainPlanConfigVO.getNextPlanDate().getTime());
			}else{
				elementMap.put("下次保养计划日期",null);
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getIsOverdueRisk())){
				elementMap.put("下次保养计划排期是否存在逾期风险",
					larkMaintainPlanConfigVO.getIsOverdueRisk() ? "是" : "否");
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getOtherOverdue())){
				elementMap.put("其他剩余计划是否存在逾期风险",
					new Integer(1).equals(larkMaintainPlanConfigVO.getOtherOverdue()) ? "是" : "否"
				);
			}
			// 凤仪的表格这个字段设计成如此，我也没办法，做多用List转Array但时间紧急先跑通再说
			String[] isPlans = new String[1];
			String isPlanDesc = new Integer(1).equals(larkMaintainPlanConfigVO.getIsPlan()) ? "有" : "无";
			isPlans[0] = isPlanDesc;
			elementMap.put("有无未来保养排期计划", isPlans);
			if(!Func.isNull(larkMaintainPlanConfigVO.getNextUserNames())){
				elementMap.put("下次保养计划执行人", larkMaintainPlanConfigVO.getNextUserNames().split(","));
			}
			elementMap.put("保养计划", larkMaintainPlanConfigVO.getTemplatePlanName());
			if(!Func.isNull(larkMaintainPlanConfigVO.getFirstTime())) {
				elementMap.put("首次保养日期", larkMaintainPlanConfigVO.getFirstTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getStartTime())) {
				elementMap.put("保养排期开始日期", larkMaintainPlanConfigVO.getStartTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getEndTime())){
				elementMap.put("保养排期结束日期",larkMaintainPlanConfigVO.getEndTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getUpdateTime())){
				elementMap.put("最后更新时间",larkMaintainPlanConfigVO.getUpdateTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getBuildingId())){
				elementMap.put("项目ID",String.valueOf(larkMaintainPlanConfigVO.getBuildingId()));
			}
			// 2024-08-29 新增
			elementMap.put("梯无忧_当前执行合同编号",larkMaintainPlanConfigVO.getContractNo());
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractBeginTime())){
				elementMap.put("梯无忧_合同服务时间(开始)",larkMaintainPlanConfigVO.getContractBeginTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractEndTime())) {
				elementMap.put("梯无忧_合同服务时间(结束)", larkMaintainPlanConfigVO.getContractEndTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractStatus())){
				Integer contractStatus = larkMaintainPlanConfigVO.getContractStatus();
				String name = ContractStatusEnum.getName(contractStatus);
				elementMap.put("梯无忧_当前执行合同管理状态",name);
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractId())) {
				String link1 = "https://admin.sida-tech.com/#/contractManage/seeContract?id=";
				Map<String, String> linkMap = new HashMap<>(2);
				linkMap.put("link", link1 + larkMaintainPlanConfigVO.getContractId());
				linkMap.put("text", "梯无忧_合同详情页链接");
				elementMap.put("梯无忧_合同详情页链接", linkMap);
			}
			elementMap.put("是否存在下一份合同",larkMaintainPlanConfigVO.getNextContractStatus());
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractSignSource())) {
				elementMap.put("合同签约来源", larkMaintainPlanConfigVO.getContractSignSource());
			}
			element.setFields(elementMap);
			records.add(element);
		}
		// 2.3 根据电梯识别码批量：更新、新增、删除飞书多维表格数据
		batchDTO.setRecords(records);
		String finalResult = feiShuDocumentService.commandCompareUpdateBatch(appToken, tableId, batchDTO, "电梯快速识别码");
		// 3. 发送飞书消息卡片到应用所在群聊
		List<JSONObject> targetGroupObjects = feiShuDocumentService.commandQueryGroupsBatch();
		List<String> chatIds = new ArrayList<>();
		targetGroupObjects.forEach(t -> chatIds.add(t.getString("chat_id")));
		// 发送消息
		chatIds.forEach(c -> {
			// 组装数据
			JSONObject bodyJson = new JSONObject();
			bodyJson.put("receive_id", c);
			bodyJson.put("msg_type", "text");
			HashMap<String, String> contentMap = new HashMap<>(2);
			String message = "定时器或表格按钮触发更新"+FeiShuDocumentEnum.getDescription(appToken,tableId)+"结果：" + finalResult;
			contentMap.put("text", message);
			// 将 contentMap 转换成 JSON 格式
			bodyJson.put("content", JSON.toJSONString(contentMap));
			feiShuDocumentService.commandSendGroupMessage(bodyJson.toJSONString());
		});
	}

	/**
	 * 异步执行方法
	 */
	@Async
	public void galaxyElevatorMaintenanceRiskDataAsync() {
		// 1. 数据准备：appToken、tableId、要更新的梯无忧列表、当前飞书多维表格的列表
		String appToken = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_RISK_DATA.getAppToken();
		String tableId = FeiShuDocumentEnum.ELEVATOR_MAINTENANCE_RISK_DATA.getTableId();
		feiShuDocumentService.commandDistinctByKeyAndUpdateTime(appToken, tableId,"电梯快速识别码","最后更新时间");
		List<LarkMaintainPlanConfigVO> maintainPlanConfigVOList = maintainPlanConfigService.getLarkMaintainPlanConfigVOList();
		// 2. 数据处理、数据update
		// 2.1 复用分页逻辑处理在保信息
		List<Integer> maintainStatusList = Arrays.asList(
			ElevatorMaintainStatusEnums.CONTRACT_IN_TIME.getId(),
			ElevatorMaintainStatusEnums.CONTRACT_OUT_TIME.getId(),
			ElevatorMaintainStatusEnums.OUT_TIME_STOP.getId(),
			ElevatorMaintainStatusEnums.OUT_TIME_END.getId(),
			ElevatorMaintainStatusEnums.OUT_TIME_END_HAS_NEXT.getId(),
			ElevatorMaintainStatusEnums.DIS_ENABLE.getId()
		);
		for (LarkMaintainPlanConfigVO planConfig : maintainPlanConfigVOList) {
			if (maintainStatusList.contains(planConfig.getMaintainStatus())) {
				Integer useType = planConfig.getUseType();
				if (!Func.equalsSafe(useType, 0)) {
					continue;
				}
				int overdueCompare= DateUtil.compare(DateUtil.date(), planConfig.getOverdueDate(), "yyyy-MM-dd");
				// 合规状态描述
				if (overdueCompare < 0) {
					planConfig.setComplianceStatus(ComplianceStatusEnum.NORMAL.getId());
					planConfig.setComplianceStatusDesc("正常");
				} else if (overdueCompare == 0) {
					planConfig.setComplianceStatus(ComplianceStatusEnum.VIOLATING.getId());
					planConfig.setComplianceStatusDesc("明天即将违规");
				} else {
					planConfig.setComplianceStatus(ComplianceStatusEnum.VIOLATED.getId());
					planConfig.setComplianceStatusDesc("已违规");
					// 比较今天和计划的天数差
					if(!Func.isNull(planConfig.getOverdueDate())){
						long overdueDays = DateUtil.between(DateUtil.date(), planConfig.getOverdueDate(), DateUnit.DAY);
						planConfig.setOverdueDays((int)overdueDays);
					}

				}
			}
			if (planConfig.getNextPlanDate() != null) {
				int riskCompare= DateUtil.compare(planConfig.getNextPlanDate(), planConfig.getOverdueDate(), "yyyy-MM-dd");
				if (riskCompare <= 0) {
					planConfig.setIsOverdueRisk(false);
				} else {
					planConfig.setIsOverdueRisk(true);
				}
			}
		}
		// 2.2 数据封装,封装时做处理
		FeiShuBatchDTO batchDTO = new FeiShuBatchDTO();
		List<FeiShuFieldsDTO> records = new ArrayList<>();
		for (LarkMaintainPlanConfigVO larkMaintainPlanConfigVO : maintainPlanConfigVOList) {
			FeiShuFieldsDTO element = new FeiShuFieldsDTO();
			Map<String, Object> elementMap = new HashMap<>(30);
			elementMap.put("电梯快速识别码", larkMaintainPlanConfigVO.getElevatorNum());
			elementMap.put("省", larkMaintainPlanConfigVO.getProvinceName());
			elementMap.put("市", larkMaintainPlanConfigVO.getCityName());
			elementMap.put("区", larkMaintainPlanConfigVO.getAdName());
			Date overdueDate = larkMaintainPlanConfigVO.getOverdueDate();
			Long overdueDateTime = null;
			if(!Func.isNull(overdueDate)){
				overdueDateTime = overdueDate.getTime();
			}
			elementMap.put("电梯_当前逾期临界日期",overdueDateTime);
			elementMap.put("项目名称",larkMaintainPlanConfigVO.getBuildingName());
			elementMap.put("楼栋号",larkMaintainPlanConfigVO.getElevatorAddress());
			elementMap.put("项目地址",larkMaintainPlanConfigVO.getAddress());
			elementMap.put("梯型式",larkMaintainPlanConfigVO.getModeName());
			String fromTypeName = null;
			Integer fromType = larkMaintainPlanConfigVO.getFromType();
			if(!Func.isNull(fromType)){
				fromTypeName = new Integer(1).equals(fromType) ? "外包"
					: new Integer(2).equals(fromType) ? "非外包" : "无状态默认值";
			}
			elementMap.put("外包情况",fromTypeName);
			String useTypeName = null;
			Integer useType = larkMaintainPlanConfigVO.getUseType();
			if(!Func.isNull(useType)){
				useTypeName = new Integer(0).equals(useType) ? "年审" : "非年审";
			}
			elementMap.put("年审类型",useTypeName);
			elementMap.put("电梯所属维保组",
				Func.isNull(larkMaintainPlanConfigVO.getDeptName()) ? "无"
					: larkMaintainPlanConfigVO.getDeptName());
			String maintainStatusName = ElevatorMaintainStatusEnums.getName(larkMaintainPlanConfigVO.getMaintainStatus());
			elementMap.put("保养状态",maintainStatusName);
			elementMap.put("电梯状态",new Integer(1).equals(larkMaintainPlanConfigVO.getIsStop()) ? "正常运行" : "停梯");
			elementMap.put("年审梯保养合规状态",larkMaintainPlanConfigVO.getComplianceStatusDesc());
			if(!Func.isNull(larkMaintainPlanConfigVO.getOverdueDays())){
				elementMap.put("违规天数", larkMaintainPlanConfigVO.getOverdueDays());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getPreviousPlanDate())){
				elementMap.put("上次维保签字日期",larkMaintainPlanConfigVO.getPreviousPlanDate().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getNextPlanDate())){
				elementMap.put("下次保养计划日期",larkMaintainPlanConfigVO.getNextPlanDate().getTime());
			}else{
				elementMap.put("下次保养计划日期",null);
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getIsOverdueRisk())){
				elementMap.put("下次保养计划排期是否存在逾期风险",
					larkMaintainPlanConfigVO.getIsOverdueRisk() ? "是" : "否");
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getOtherOverdue())){
				elementMap.put("其他剩余计划是否存在逾期风险",
					new Integer(1).equals(larkMaintainPlanConfigVO.getOtherOverdue()) ? "是" : "否"
				);
			}
			// 凤仪的表格这个字段设计成如此，我也没办法，做多用List转Array但时间紧急先跑通再说
			String[] isPlans = new String[1];
			String isPlanDesc = new Integer(1).equals(larkMaintainPlanConfigVO.getIsPlan()) ? "有" : "无";
			isPlans[0] = isPlanDesc;
			elementMap.put("有无未来保养排期计划", isPlans);
			if(!Func.isNull(larkMaintainPlanConfigVO.getNextUserNames())){
				elementMap.put("下次保养计划执行人", larkMaintainPlanConfigVO.getNextUserNames().split(","));
			}
			elementMap.put("保养计划", larkMaintainPlanConfigVO.getTemplatePlanName());
			if(!Func.isNull(larkMaintainPlanConfigVO.getFirstTime())) {
				elementMap.put("首次保养日期", larkMaintainPlanConfigVO.getFirstTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getStartTime())) {
				elementMap.put("保养排期开始日期", larkMaintainPlanConfigVO.getStartTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getEndTime())){
				elementMap.put("保养排期结束日期",larkMaintainPlanConfigVO.getEndTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getUpdateTime())){
				elementMap.put("最后更新时间",larkMaintainPlanConfigVO.getUpdateTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getBuildingId())){
				elementMap.put("项目ID",String.valueOf(larkMaintainPlanConfigVO.getBuildingId()));
			}
			// 2024-08-29 新增
			elementMap.put("梯无忧_当前执行合同编号",larkMaintainPlanConfigVO.getContractNo());
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractBeginTime())){
				elementMap.put("梯无忧_合同服务时间(开始)",larkMaintainPlanConfigVO.getContractBeginTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractEndTime())) {
				elementMap.put("梯无忧_合同服务时间(结束)", larkMaintainPlanConfigVO.getContractEndTime().getTime());
			}
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractStatus())){
				Integer contractStatus = larkMaintainPlanConfigVO.getContractStatus();
				String name = ContractStatusEnum.getName(contractStatus);
				elementMap.put("梯无忧_当前执行合同管理状态",name);
			}
			elementMap.put("是否存在下一份合同",larkMaintainPlanConfigVO.getNextContractStatus());
			if(!Func.isNull(larkMaintainPlanConfigVO.getContractSignSource())) {
				elementMap.put("合同签约来源", larkMaintainPlanConfigVO.getContractSignSource());
			}
			element.setFields(elementMap);
			records.add(element);
		}
		// 2.3 根据电梯识别码批量：更新、新增、删除飞书多维表格数据
		batchDTO.setRecords(records);
		String finalResult = feiShuDocumentService.commandCompareUpdateBatch(appToken, tableId, batchDTO, "电梯快速识别码");
		// 3. 发送飞书消息卡片到应用所在群聊
		List<JSONObject> targetGroupObjects = feiShuDocumentService.commandQueryGroupsBatch();
		List<String> chatIds = new ArrayList<>();
		targetGroupObjects.forEach(t -> chatIds.add(t.getString("chat_id")));
		// 发送消息
		chatIds.forEach(c -> {
			// 组装数据
			JSONObject bodyJson = new JSONObject();
			bodyJson.put("receive_id", c);
			bodyJson.put("msg_type", "text");
			HashMap<String, String> contentMap = new HashMap<>(2);
			String message = "定时器或表格按钮触发更新"+FeiShuDocumentEnum.getDescription(appToken,tableId)+"结果：" + finalResult;
			contentMap.put("text", message);
			// 将 contentMap 转换成 JSON 格式
			bodyJson.put("content", JSON.toJSONString(contentMap));
			feiShuDocumentService.commandSendGroupMessage(bodyJson.toJSONString());
		});
	}

}
